package cn.btks.zuulserver.security;

import cn.btks.commonserver.result.ResultState;
import cn.btks.zuulserver.dto.Menu;
import cn.btks.zuulserver.dto.Role;
import cn.btks.zuulserver.feign.service.backmanage.BackManageClient;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @Author lijun
 * @Date 2021/1/9 14:32
 *
 * 功能:通过当前的请求地址，获取该地址需要的用户角色
 */
@Slf4j
@Component
public class UrlFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Autowired
    BackManageClient backManageClient;

    AntPathMatcher antPathMatcher = new AntPathMatcher();

    @SneakyThrows
    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        //获取请求地址
        String requestUrl = ((FilterInvocation)o).getRequestUrl();
        log.info("requestUrl:"+requestUrl);
        //如果地址是 /login，这个是登录页，不需要任何角色即可访问
        if ("/login".equals(requestUrl)) {
            return null;
        }
        List<Menu> menuList = new ArrayList<>();
        ResultState resultState = backManageClient.findAll();
        if(resultState.getData() != null){
            Object data = resultState.getData();
            menuList = JSONArray.parseArray(JSON.toJSONString(data), Menu.class);
        }

        if(menuList != null && menuList.size() > 0){
            for(Menu menu : menuList){
                if(menu.getUrl() == null){
                    continue;
                }
                if(antPathMatcher.match(menu.getUrl(),requestUrl) && menu.getRoles().size() > 0){
                    List<Role> roles = menu.getRoles();
                    String[] values = new String[roles.size()];
                    for(int i = 0; i < roles.size(); i++){
                        values[i] = roles.get(i).getRoleCode();
                    }
                    return SecurityConfig.createList(values);
                }
            }
        }
        //没有匹配上的资源，都是登录访问
        return SecurityConfig.createList("ROLE_LOGIN");
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return FilterInvocation.class.isAssignableFrom(aClass);
    }
}
